package main

import (
	"bufio"
	"code.google.com/p/go.text/encoding/simplifiedchinese"
	"code.google.com/p/go.text/transform"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"time"
)

var PPathUnityExec = flag.String("UnityPath", `D:\Program Files (x86)\Unity\Editor\Unity.exe`, "Unity exe path")
var PPathResources = flag.String("ResPath", `F:\dorDev\《哆啦A梦跑酷》数据表\csv\*.csv`, "Resources to build ,can use *.*")
var PPathBundle = flag.String("BundlePath", ``, "Build Bundle path")

func main() {
	flag.Parse()
	var err error

	workDir, errT0 := filepath.Abs(filepath.Dir(os.Args[0]))
	ExitIfErr(errT0)

	if len(*PPathResources) == 0 {
		*PPathResources = workDir + "/*.txt"
	}
	if len(*PPathBundle) == 0 {
		*PPathBundle = workDir + "\\" + fmt.Sprintf("tmpBundle%d_%d_%d", time.Now().Hour(), time.Now().Minute(), time.Now().Second())
	}

	//tmpUnityPrjName, errT1 := filepath.Abs(fmt.Sprintf("tmpUnityPrj%d_%d_%d", time.Now().Hour(), time.Now().Minute(), time.Now().Second()))
	// ExitIfErr(errT1)

	tmpUnityPrjName := fmt.Sprintf("C:\\tmpUnityPrj%d_%d_%d", time.Now().Hour(), time.Now().Minute(), time.Now().Second())

	pathUnityPrjAssets := tmpUnityPrjName + "\\Assets"

	Cmd(*PPathUnityExec, "-batchmode", "-quit", "-createProject", tmpUnityPrjName)
	defer func() {
		if _, err := os.Stat(tmpUnityPrjName); err == nil {
			Cmd("cmd", "/C", "rmdir", tmpUnityPrjName, "/s", "/q")
		}

	}()
	Cmd("xcopy", *PPathResources, pathUnityPrjAssets, "/Y")

	files, errT := ioutil.ReadDir(pathUnityPrjAssets)
	ExitIfErr(errT)
	if len(files) == 0 {
		ExitIfErr(errors.New("Not any resources at " + *PPathResources))
	}

	resPaths := make([]string, len(files))
	for i, f := range files {
		resPaths[i] = "Assets\\" + f.Name()
	}

	cscode :=
		`using UnityEngine;
		using UnityEditor;
		using System.Collections;
		using System.Collections.Generic;

		public class AssetsBundler
		{
		    static void Bundle()
		    {
		        var assetPathsList = new List<string>();`
	for _, fPath := range resPaths {
		cscode += fmt.Sprintf("\nassetPathsList.Add(@\"%s\");\n", fPath)
	}

	cscode += `ArrayList assetList = new ArrayList();

		        foreach(string assetPath in assetPathsList)
		        {
		            Debug.Log("Loading " + assetPath);
		            UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(assetPath);
		            foreach(UnityEngine.Object asset in assets)
		            {
		                Debug.Log("Found asset: " + asset.name);
		                assetList.Add(asset);
		            }
		        }

		        UnityEngine.Object[] allAssets = (UnityEngine.Object[]) assetList.ToArray(typeof(UnityEngine.Object));
		        BuildPipeline.BuildAssetBundle(null, allAssets,@"` + *PPathBundle + `.android.bundle",BuildAssetBundleOptions.CompleteAssets, BuildTarget.Android);
		        BuildPipeline.BuildAssetBundle(null, allAssets,@"` + *PPathBundle + `.ios.bundle",BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone);
		        BuildPipeline.BuildAssetBundle(null, allAssets,@"` + *PPathBundle + `.win.bundle",BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);
		    }
		}`

	cscode = Utf8ToGBK(cscode)
	// -batchmode -quit -createProject ${ASSET_BUNDLE_PROJECT_DIR};
	err = ioutil.WriteFile(pathUnityPrjAssets+"/AssetsBundler.cs", []byte(cscode), 0644)
	ExitIfErr(err)
	//Cmd(workDir+"\\Utf8ToGbk", pathUnityPrjAssets+"\\AssetsBundler.cs")

	Cmd(*PPathUnityExec, "-batchmode", "-quit", "-projectPath", tmpUnityPrjName, "-executeMethod", "AssetsBundler.Bundle")

	fmt.Println(fmt.Sprintf("build %d bundles success.", len(files)))

	// bufio.NewReader(os.Stdin).ReadByte()
}

func ExitIfErr(e error) {
	if e != nil {
		fmt.Println(e)
		bufio.NewReader(os.Stdin).ReadByte()
		os.Exit(1)
	}
}

func Cmd(name string, arg ...string) {
	cmd := exec.Command(name, arg...)
	err := cmd.Run()
	ExitIfErr(err)
}

func Utf8ToGBK(utf8 string) string {
	gbk, _, err := transform.String(simplifiedchinese.GBK.NewEncoder(), utf8)
	if err != nil {
		panic(err)
	}
	return gbk
}

// #!/bin/bash

// UNITY_EXEC=/Applications/Unity/Unity.app/Contents/MacOS/Unity

// if [ -z "$2" ]; then
//   echo "You must provide a path to the bundle assets and a path to the resulting bundle.";
//   exit 1;
// fi

// export UNITY_ASSET_BUNDLE_PATH=${2}

// CREATION_TIME=`date +%s`
// ASSET_BUNDLE_PROJECT_DIR=/tmp/AssetBundle-${CREATION_TIME}

// echo "Creating temporary project.";
// ${UNITY_EXEC} -batchmode -quit -createProject ${ASSET_BUNDLE_PROJECT_DIR};

// # Copy the project assets from the source folder
// echo "Copying resources from source folder to assets folder.";
// cd $1;
// cp -r . ${ASSET_BUNDLE_PROJECT_DIR}/Assets;

// echo "Finding assets.";
// cd ${ASSET_BUNDLE_PROJECT_DIR};
// ASSETS_TO_BUNDLE=`find Assets -type f -name "*.*" | sed 's/^.\///g' | sed 's/^/assetPathsList.Add("/g' | sed 's/$/");/g'`

// # Copy the bundler script into the project
// mkdir ${ASSET_BUNDLE_PROJECT_DIR}/Assets/Editor/;
// cat > ${ASSET_BUNDLE_PROJECT_DIR}/Assets/Editor/AssetsBundler.cs  assetPathsList = new List();
//            ${ASSETS_TO_BUNDLE};

//            ArrayList assetList = new ArrayList();

//            foreach(string assetPath in assetPathsList)
//            {
//              Debug.Log("Loading " + assetPath);
//              UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(assetPath);
//              foreach(UnityEngine.Object asset in assets)
//              {
//                 Debug.Log("Found asset: " + asset.name);
//                 assetList.Add(asset);
//              }
//            }

//            UnityEngine.Object[] allAssets = (UnityEngine.Object[]) assetList.ToArray(typeof(UnityEngine.Object));
//            BuildPipeline.BuildAssetBundle(null, allAssets, "${UNITY_ASSET_BUNDLE_PATH}", BuildAssetBundleOptions.CompleteAssets);
//     }
// }
// END

// echo "Building the bundle.";
// ${UNITY_EXEC} -batchmode -quit -projectProject ${ASSET_BUNDLE_PROJECT_DIR} -executeMethod AssetsBundler.Bundle;

// echo "Deleting temporary project.";
// rm -rf ${ASSET_BUNDLE_PROJECT_DIR};
